package com.logos.musicframe.service.impl;

import com.alibaba.fastjson.JSON;
import com.logos.musicframe.constant.RedisConstant;
import com.logos.musicframe.constant.MqConstant;
import com.logos.musicframe.converter.SongsConverter;
import com.logos.musicframe.entity.LikedCount;
import com.logos.musicframe.entity.Songs;
import com.logos.musicframe.entity.SongsLiked;
import com.logos.musicframe.mapper.SongsLikedMapper;
import com.logos.musicframe.mapper.SongsMapper;
import com.logos.musicframe.resp.SongsResp;
import com.logos.musicframe.service.SongsLikedService;
import com.logos.musicframe.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 点赞行为记录表(SongsLiked)表服务实现类
 *
 * @author rose
 * @since 2025-06-02 22:58:24
 */
@Service("songsLikedService")
@Slf4j
public class SongsLikedServiceImpl implements SongsLikedService {
    @Autowired
    private SongsLikedMapper songsLikedMapper;

    @Autowired
    private SongsMapper songsMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public SongsLiked queryById(Long id) {
        return this.songsLikedMapper.queryById(id);
    }

    /**
     * 新增数据
     *
     * @param songsLiked 实例对象
     * @return 实例对象
     */
    @Override
    public SongsLiked insert(SongsLiked songsLiked) {
        this.songsLikedMapper.insert(songsLiked);
        return songsLiked;
    }

    /**
     * 修改数据
     *
     * @param songsLiked 实例对象
     * @return 实例对象
     */
    @Override
    public SongsLiked update(SongsLiked songsLiked) {
        this.songsLikedMapper.update(songsLiked);
        return this.queryById(songsLiked.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Long id) {
        return this.songsLikedMapper.deleteById(id) > 0;
    }

    @Override
    public List<SongsResp> getUserLikedSongs(Integer userId) {
        // 先检查缓存中是否存在
        if (redisUtil.exist(RedisConstant.SONG_LIKED_USER + userId)) {
            String songsRespListStr = redisUtil.get(RedisConstant.SONG_LIKED_USER + userId);
            List<SongsResp> songsRespList = JSON.parseArray(songsRespListStr, SongsResp.class);
            System.out.println("songsService.getUserLikedSongs.Cache.Hit:" + songsRespList);
            return songsRespList;
        }
        // 根据用户id去数据库中查询当前用户的点赞过的歌曲 分页查询 查前十条
        // TODO 这里随便做的,按理说还要分页req
        SongsLiked songsLiked = new SongsLiked();
        songsLiked.setUserId(userId);
        int pageNum = 0;
        int pageSize = 10;
        Pageable pageable = PageRequest.of(pageNum, pageSize);
        List<SongsLiked> songsLikedList = songsLikedMapper.queryAllByLimit(songsLiked, pageable);
        if (songsLikedList == null || songsLikedList.isEmpty()) {
            return Collections.emptyList();
        }
        // 获取到歌曲id集合
        List<Integer> songIdSet = songsLikedList.stream().map(SongsLiked::getSongId).toList();
        if (songIdSet == null || songIdSet.isEmpty()) {
            return Collections.emptyList();
        }
        List<Songs> songsList = songsMapper.queryByIds(songIdSet.stream().toList());
        if (songsList == null || songsList.isEmpty()) {
            return Collections.emptyList();
        }
        List<SongsResp> songsRespList = songsList.stream().map(SongsConverter.INSTANCE::convertEntityToResp).collect(Collectors.toList());
        for (SongsResp songsResp : songsRespList) {
            songsResp.setIsLiked(true);
        }
        // 存入redis
        redisUtil.setNx(RedisConstant.SONG_LIKED_USER + userId, JSON.toJSONString(songsRespList), RedisConstant.EXPIRE_TIME_THREE_MINUTES);
        return songsRespList;
    }

    @Override
    public boolean likeSong(Integer userId, Integer songId) {
        // 向mq发送点赞消息
        try {
            SongsLiked songsLiked = new SongsLiked().setSongId(songId).setUserId(userId);
            rabbitTemplate.convertAndSend(MqConstant.SONGS_EXCHANGE, MqConstant.SONGS_LIKED_ROUTING_KEY, songsLiked);
        } catch (Exception e) {
            log.error("发送点赞消息失败：{}", e);
            return false;
        }
        // 利用mq发送消息增加数据库中点赞个数
        try {
            LikedCount likedCount = new LikedCount().setSongId(songId).setCount(1);
            rabbitTemplate.convertAndSend(MqConstant.SONGS_EXCHANGE, MqConstant.SONGS_LIKED_COUNT_ROUTING_KEY, likedCount);
        }catch (Exception e){
            log.error("发送增加点赞个数消息失败：{}", e);
            return false;
        }
        // 将redis中排行榜个数增加1
        redisUtil.addScore(RedisConstant.SONG_RANK, String.valueOf(songId), 1L);
        // 删除点赞缓存和查询全部歌曲缓存
        redisUtil.del(RedisConstant.SONG_LIKED_USER + userId);
        redisUtil.del(RedisConstant.ALL_SONG);
        return true;
    }

    @Override
    public boolean unlikeSong(Integer userId, Integer songId) {
        // 向mq发送取消点赞消息
        try {
            SongsLiked songsLiked = new SongsLiked().setSongId(songId).setUserId(userId);
            rabbitTemplate.convertAndSend(MqConstant.SONGS_EXCHANGE, MqConstant.SONGS_UNLIKED_ROUTING_KEY, songsLiked);
        } catch (Exception e) {
            log.error("发送取消点赞消息失败：{}", e);
            return false;
        }
        // 利用mq发送消息减少数据库中点赞个数
        try {
            LikedCount likedCount = new LikedCount().setSongId(songId).setCount(-1);
            rabbitTemplate.convertAndSend(MqConstant.SONGS_EXCHANGE, MqConstant.SONGS_LIKED_COUNT_ROUTING_KEY, likedCount);
        }catch (Exception e){
            log.error("发送增加点赞个数消息失败：{}", e);
            return false;
        }
        // 将redis中排行榜个数减少1
        redisUtil.addScore(RedisConstant.SONG_RANK, String.valueOf(songId), -1L);
        // 同时删除点赞缓存和个人用户点赞列表缓存和全部歌曲缓存
        redisUtil.del(RedisConstant.SONG_LIKED_USER + userId);
        redisUtil.del(RedisConstant.ALL_SONG);
        return true;
    }


    /**
     * 查询一首歌是否被用户点过赞
     *
     * @param userId
     * @param songId
     * @return
     */
    @Override
    public boolean isLiked(Integer userId, Integer songId) {
        SongsLiked songsLiked = new SongsLiked().setUserId(userId).setSongId(songId);
        List<SongsLiked> songsLikedList = songsLikedMapper.queryByCondtion(songsLiked);
        if (songsLikedList != null && !songsLikedList.isEmpty()) {
            return true;
        }
        return false;
    }
}
